package com.softserveinc.moviedbapp.widget;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.SystemClock;
import android.util.Log;
import android.widget.RemoteViews;

import com.softserveinc.moviedbapp.R;
import com.softserveinc.moviedbapp.model.Movie;
import com.softserveinc.moviedbapp.util.MovieAppConstants;

public class MovieWidgetProvider extends AppWidgetProvider {

	private static final String APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
	private static final String TAG = MovieWidgetProvider.class.getSimpleName();
	private Context mContext;

	@Override
	public void onReceive(final Context context, final Intent intent) {
		mContext = context;
		Log.d(TAG, "in onReceive() and action is " + intent.getAction());
		String action = intent.getAction();
		if (action.equals("update.yourself.you.focker") || action.equals(APPWIDGET_UPDATE)) {
			updateWidget(intent);
		} else {
			super.onReceive(context, intent);
		}
	}

	@Override
	public void onDeleted(final Context context, final int[] appWidgetIds) {
		Log.d(TAG, "in onDeleted() setting alarm to -1");
		SharedPreferences prefs = context.getSharedPreferences(WidgetPreferencesConstants.PREFS_FILE, 0);
		Editor editor = prefs.edit();
		for (int appWidgetId : appWidgetIds) {
			setAlarm(context, appWidgetId, -1);
			removeWidgetSettings(editor, appWidgetId);
		}
		super.onDeleted(context, appWidgetIds);
	}

	@Override
	public void onDisabled(final Context context) {
		Log.d(TAG, "in onDisabled() stopping service");
		context.stopService(new Intent(context, UpdateService.class));
		super.onDisabled(context);
	}

	@Override
	public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {

		for (int appWidgetId : appWidgetIds) {

			SharedPreferences prefs = context.getSharedPreferences(WidgetPreferencesConstants.PREFS_FILE, 0);
			int updateRate = prefs.getInt(WidgetPreferencesConstants.UPDATE_NEXT_MOVIE + appWidgetId, 30);

			Log.d(TAG, "in onUpdate() setting alarm to update rate " + updateRate * 1000);
			setAlarm(context, appWidgetId, updateRate * 1000);

		}
	}

	public static void setAlarm(final Context context, final int appWidgetId, final int updateRate) {

		PendingIntent newPendingIntent = createPendingIntent(context, UpdateService.UPDATE, appWidgetId);
		AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
		if (updateRate >= 0) {
			Log.d(TAG, "inside setAlarm() setting alarms.setRepeating to update rate " + updateRate);

			/* This alarm does not wake the device up; if it goes off while the device is asleep, it will not be
			 * delivered until the next time the device wakes up */
			alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + updateRate, updateRate,
					newPendingIntent);
		} else {
			// on a negative updateRate stop the refreshing
			alarms.cancel(newPendingIntent);
		}
	}

	public static PendingIntent createPendingIntent(final Context context, final String action, final int appWidgetId) {
		Intent intent;
		if (action.equals(UpdateService.CONFIGURE)) {
			intent = new Intent(context, com.softserveinc.moviedbapp.widget.WidgetConfigurePreferenceActivity.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.setAction(action);
			intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
			Log.d(TAG, "in createPendingIntent() action is " + action);
			// this Uri data is to make the PendingIntent unique, so it wont be updated by FLAG_UPDATE_CURRENT
			// so if there are multiple widget instances they wont override each other
			Uri data = Uri.withAppendedPath(Uri.parse("moviewidget://widget/id/#" + action + appWidgetId),
					String.valueOf(appWidgetId));
			intent.setData(data);

			return (PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
		} else {
			intent = new Intent(context, UpdateService.class);
			intent.setAction(action);
			intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
			Log.d(TAG, "in createPendingIntent() action is " + action);
			// this Uri data is to make the PendingIntent unique, so it wont be updated by FLAG_UPDATE_CURRENT
			// so if there are multiple widget instances they wont override each other
			Uri data = Uri.withAppendedPath(Uri.parse("moviewidget://widget/id/#" + action + appWidgetId),
					String.valueOf(appWidgetId));
			intent.setData(data);

			return (PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
		}
	}

	public static PendingIntent createPendingIntentMovieDetails(final Context context, final String action,
			final Movie movie) {
		Intent intent = new Intent(context, com.softserveinc.moviedbapp.application.MovieDBMainActivity.class);
		intent.setAction(action);
		intent.putExtra(MovieAppConstants.MOVIE_OBJECT, movie);
		Log.d(TAG, "in createPendingIntent() action is " + action);

		return (PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
	}

	private void updateWidget(final Intent intent) {
		Log.d(TAG, "in updateWidget() and action is " + intent.getAction());
		// Push update for this widget to the home screen
		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
		Movie movie = (Movie) intent.getParcelableExtra(MovieAppConstants.MOVIE_OBJECT);
		int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);

		if (movie == null) {
			createPendingIntent(mContext, UpdateService.UPDATE_CONFIG_CHANGED, appWidgetId);
		} else {
			RemoteViews remoteViews = buildUpdate(movie);

			remoteViews.setOnClickPendingIntent(R.id.widget_configure_btn,
					MovieWidgetProvider.createPendingIntent(mContext, UpdateService.CONFIGURE, appWidgetId));
			remoteViews.setOnClickPendingIntent(R.id.widget_info_area, MovieWidgetProvider
					.createPendingIntentMovieDetails(mContext, UpdateService.SHOW_MOVIE_DETAILS, movie));
			remoteViews.setOnClickPendingIntent(R.id.widget_poster,
					MovieWidgetProvider.createPendingIntent(mContext, UpdateService.UPDATE_ITSELF, appWidgetId));

			// apply changes to widget
			appWidgetManager.updateAppWidget(appWidgetId, remoteViews);

			onUpdate(mContext, appWidgetManager, new int[] { appWidgetId });
		}

	}

	private RemoteViews buildUpdate(final Movie currentMovie) {

		Log.d(TAG, "buildUpdate() building...");
		RemoteViews updateViews = new RemoteViews(mContext.getPackageName(), R.layout.movie_widget_layout);

		Log.d(TAG, "buildUpdate() got movie...");
		/* set the poster url */
		Bitmap posterBitmap = currentMovie.getPosterBitmap();
		if (posterBitmap != null) {
			updateViews.setImageViewBitmap(R.id.widget_poster, posterBitmap);
		} else {
			updateViews.setImageViewResource(R.id.widget_poster, R.drawable.not_available);
		}

		/* set movie title and release date and rating */
		updateViews.setTextViewText(R.id.widget_movieName, currentMovie.getName());
		updateViews.setTextViewText(R.id.widget_releaseDate, currentMovie.getReleased());
		updateViews.setTextViewText(R.id.widget_rating, String.valueOf(currentMovie.getRating()));

		/* set the proper certification image */
		if (currentMovie.getCertification().equals("PG-13")) {
			updateViews.setImageViewResource(R.id.widget_certification, R.drawable.rating_pg13);
		} else if (currentMovie.getCertification().equals("R")) {
			updateViews.setImageViewResource(R.id.widget_certification, R.drawable.rating_r);
		} else if (currentMovie.getCertification().equals("NR")) {
			updateViews.setImageViewResource(R.id.widget_certification, R.drawable.rating_nr);
		} else if (currentMovie.getCertification().equals("PG")) {
			updateViews.setImageViewResource(R.id.widget_certification, R.drawable.rating_pg);
		} else if (currentMovie.getCertification().equals("G")) {
			updateViews.setImageViewResource(R.id.widget_certification, R.drawable.rating_g);
		} else {
			updateViews.setImageViewResource(R.id.widget_certification, R.drawable.rating_nr);
		}

		return updateViews;
	}

	/* removes widget's settings from shared preferences */
	private void removeWidgetSettings(final Editor editor, final int appWidgetId) {
		Log.d(TAG, "in removeWidgetSettings() removing widget's settings " + appWidgetId);
		editor.remove("updateNextMovie" + appWidgetId);
		editor.remove("updateMovieList" + appWidgetId);
		editor.remove("results" + appWidgetId);
		editor.remove("orderBy" + appWidgetId);

		editor.commit();
	}

}
